/******************************************
Cola_implementacion_lista.java
Universidad del Valle de Guatemala
Algoritmos y Estructura de Datos
Autor:
    Martín Guzmán
Fecha: 15 de julio de 2009
Descripción: Implementación de una cola
 * utilizando listas circulares
*******************************************/

import java.lang.reflect.Array;
import java.lang.AssertionError;
import java.util.LinkedList;

public class Conjunto<G> extends Conjunto_Abstracto<G> {

    //método constructor
    public Conjunto(){
        super();
    }

    public Conjunto(LinkedList<G> lista){
        super();
        //System.out.println("Tamaño entrante: "+lista.size()); //debuguear
        for(int i=0;i<lista.size();i++){
            this.Lista_conjunto.add(lista.get(i));
        }

        //System.out.println("generar árbol");
        Arbol_conjunto = new Arbol_2_3(this.Lista_conjunto);
        //System.out.println("terminó de generar árbol");


    }

    public String toString(){

        Nodo<String> nodo = null;
        String temporal = "";

        try{
            nodo = this.Arbol_conjunto.Generar_arbol(this.Lista_conjunto);

            temporal="{"+nodo.Mostrar_Nodo();

            if(temporal.endsWith(",")){
                temporal=temporal.substring(0,temporal.length()-1);
            }

            while(true){
                if(temporal.contains(",,")==true){
                    temporal=temporal.replaceAll(",,",",");
                }
                else
                    break;
            }
            temporal+="}"; //va a tener formato: {#,#, ... ,#,#}
            //System.out.println("Con árboles: "+temporal+"");
            return temporal;

        }catch(Exception exp){
            return "{}";
        }
    }

    public Conjunto<G> Interseccion(Conjunto B) {
        //intersección entre THIS y B

        Conjunto C = new Conjunto();

        //copiar la lista de A
        LinkedList<G> lista_temporal_A = new LinkedList<G>();
        for(int i=0;i<this.Lista_conjunto.size();i++){
            lista_temporal_A.add(this.Lista_conjunto.get(i));
        }
        //copiar la lista de B
        LinkedList<G> lista_temporal_B = new LinkedList<G>();
        for(int i=0;i<B.Lista_conjunto.size();i++){
            lista_temporal_B.add((G)B.getLista_conjunto().get(i));
        }

        //System.out.println(lista_temporal_A.size()+"   "+lista_temporal_B.size()); //tamaños

        LinkedList<G> lista_temporal_C = new LinkedList<G>();

        for(int i=0;i<lista_temporal_A.size();i++){
            G temp_A = lista_temporal_A.get(i);
            //recorre todo B por cada elemento de A buscando que exista
            for(int j=0;j<lista_temporal_B.size();j++){
                //si existe significa que pertenece a ambos y lo agrega
                //a la lista de intersección

                //System.out.println(temp_A.toString()+"   "+lista_temporal_B.get(j).toString()); //comparar elemento de A con B

                if(temp_A.equals(lista_temporal_B.get(j))){
                    lista_temporal_C.add(temp_A);
                }
            }
        }

        C = new Conjunto(lista_temporal_C);

        return C;
    }

    public Conjunto<G> Union(Conjunto B) {
        //unión entre THIS y B

        Conjunto C = null;

        //copiar la lista de A
        LinkedList<G> lista_temporal_A = new LinkedList<G>();
        for(int i=0;i<this.Lista_conjunto.size();i++){
            lista_temporal_A.add(this.Lista_conjunto.get(i));
        }
        //copiar la lista de B
        LinkedList<G> lista_temporal_B = new LinkedList<G>();
        for(int i=0;i<B.Lista_conjunto.size();i++){
            lista_temporal_B.add((G)B.getLista_conjunto().get(i));
        }

        LinkedList<G> lista_temporal_C = new LinkedList<G>();
        //recorre los elementos de A
        for(int i=0;i<lista_temporal_A.size();i++){
            //agrega todos los elementos de A
            lista_temporal_C.add(lista_temporal_A.get(i));
        }
        //recorre los elementos de B
        for(int i=0;i<lista_temporal_B.size();i++){
            //agrega los elementos de B que no se encuentren ya en la lista
            G temp_B = lista_temporal_B.get(i);

            if(lista_temporal_C.indexOf(temp_B)==-1){
                //si es -1 no se encuentra aún en la lista
                lista_temporal_C.add(lista_temporal_B.get(i));
            }

        }


        C = new Conjunto(lista_temporal_C);


        return C;
    }


}